/*
 * 实现了通信相关的基类和函数接口
 */
#pragma once
#include <memory>
#include <functional>
#include "fields.hpp"

namespace jsonrpc
{
    // 基础消息类型
    class BaseMessage
    {
    public:
        using ptr = std::shared_ptr<BaseMessage>;
        virtual ~BaseMessage() = default;
        // 设置消息id
        virtual void setRid(const std::string &id)
        {
            r_id = id;
        }
        // 获取消息id
        virtual std::string getRid() const
        {
            return r_id;
        }
        // 设置消息类型
        virtual void setMessageType(MType type)
        {
            m_type = type;
        }
        // 获取消息类型
        virtual MType getMessageType() const
        {
            return m_type;
        }
        // 序列化
        virtual std::string serialize() = 0;
        // 反序列化
        virtual bool deserialize(const std::string &msg) = 0;
        // 检查消息是否合法
        virtual bool check() = 0;

    private:
        MType m_type;     // 消息类型
        std::string r_id; // 消息id
    };

    // 基础缓冲区类型
    class BaseBuffer
    {
    public:
        using ptr = std::shared_ptr<BaseBuffer>;
        virtual ~BaseBuffer() = default;
        // 返回可读数据的大小
        virtual size_t readableSize() = 0;
        // 查看缓冲区中的下一个32位整数，但不移除它
        virtual int32_t peekInt32() = 0;
        // 移除缓冲区中的下一个32位整数
        virtual void retrieveInt32() = 0;
        // 读取缓冲区中的下一个32位整数，并移除它
        virtual int32_t readInt32() = 0;
        // 从缓冲区中读取指定长度的字符串，并移除这些数据
        virtual std::string retrieveAsString(size_t len) = 0;
    };

    // 基础协议类型
    class BaseProtocol
    {
    public:
        virtual ~BaseProtocol() = default;
        using ptr = std::shared_ptr<BaseProtocol>;
        // 检查是否可以处理该缓冲区
        virtual bool canProcessed(const BaseBuffer::ptr &buf) = 0;
        // 处理缓冲区中的数据，并返回消息
        virtual bool onMessage(const BaseBuffer::ptr &buf, BaseMessage::ptr &msg) = 0;
        // 序列化消息
        virtual std::string serialize(const BaseMessage::ptr &msg) = 0;
    };

    // 基础连接类型
    class BaseConnection
    {
    public:
        virtual ~BaseConnection() = default;
        using ptr = std::shared_ptr<BaseConnection>;
        // 发送消息
        virtual void send(const BaseMessage::ptr &msg) = 0;
        // 关机
        virtual void shutdown() = 0;
        // 判断是否连接
        virtual bool connected() = 0;
    };

    // 回调函数类型
    using ConnectionCallback = std::function<void(const BaseConnection::ptr &)>;
    using CloseCallback = std::function<void(const BaseConnection::ptr &)>;
    using MessageCallback = std::function<void(const BaseConnection::ptr &, BaseMessage::ptr &)>;

    // 基础服务器类型
    class BaseServer
    {
    public:
        virtual ~BaseServer() = default;
        using ptr = std::shared_ptr<BaseServer>;
        // 启动服务
        virtual void start() = 0;
        // 设置连接回调函数
        virtual void setConnectionCallback(const ConnectionCallback &cb)
        {
            connection_cb = cb;
        }
        // 设置关闭回调函数
        virtual void setCloseCallback(const CloseCallback &cb)
        {
            close_cb = cb;
        }
        // 设置消息回调函数
        virtual void setMessageCallback(const MessageCallback &cb)
        {
            message_cb = cb;
        }

    protected:
        ConnectionCallback connection_cb;
        CloseCallback close_cb;
        MessageCallback message_cb;
    };

    // 基础客户端类型
    class BaseClient
    {
    public:
        virtual ~BaseClient() = default;
        using ptr = std::shared_ptr<BaseClient>;
        // 设置连接回调函数
        virtual void setConnectionCallback(const ConnectionCallback &cb)
        {
            connection_cb = cb;
        }
        // 设置关闭回调函数
        virtual void setCloseCallback(const CloseCallback &cb)
        {
            close_cb = cb;
        }
        // 设置消息回调函数
        virtual void setMessageCallback(const MessageCallback &cb)
        {
            message_cb = cb;
        }
        // 连接
        virtual void connect() = 0;
        // 关闭
        virtual void shutdown() = 0;
        // 判断是否连接
        virtual bool connected() = 0;
        // 发送消息
        virtual bool send(const BaseMessage::ptr &msg) = 0;
        // 返回连接指针
        virtual BaseConnection::ptr connection() = 0;

    protected:
        ConnectionCallback connection_cb;
        CloseCallback close_cb;
        MessageCallback message_cb;
    };
}
